<?php
namespace Duobao\Model;

use Com\Weixin\WeixinApi;
use Think\Model;
use Duobao\Controller\LogController as MyLog;

class PingModel extends Model{
    protected $tableName = 'member_addmoney_record';

    /**
     * 用户获取云购号码
     * 返回中奖号码串，以逗号隔开
     */
    private function getCode($goodsId,$c_id,$number){
        $model = new \Think\Model();
        # MyLog::write('进入分配号码');

        #获取表名
        $condition['key'] = 'shopcodes_table';
        $table = $model->table("__CACHES__")->where($condition)->getField('value');

        $tableName = "__SHOPCODES_".$table."__";
        #MyLog::write("tablename:".$tableName);
        #获取云购码的内容
        $where['s_id'] = $goodsId;
        #因为后台添加商品的时候，在一个商品的价格大于3000的时候会分记录存储，所以需要求改原来的逻辑
        $count = $model->table($tableName)->where($where)->sum('s_len');
        #MyLog::write("总数:".$count);

        #修改最后一个不能买的bug
        if($count >= $number){
            #MyLog::write("总数大于用户购买数量");
            #分析$arr 获取选取记录的位置和相应的条数
            #获取对应id的商品序列code
            $code = '';
            $result = $model->table($tableName)->field('id,s_len,s_codes')->where($where)->select();

            foreach($result as $val){
                if($val['s_len'] == 0){
                    #MyLog::write("当前该条记录为空,跳过本次循环");
                    continue;#结束本次循环进入下一次循环
                }elseif($val['s_len'] <= $number){
                    #MyLog::write("当前的记录数小于等于用户购买的数量,直接将当前记录分配出去");
                    #$code = implode(',',array_splice($result,0,$number));
                    $code .= implode(',',unserialize($val['s_codes']));
                    $number = $number - $val['s_len'];//减去数量
                    #修改数据库
                    $data['s_len'] = 0;
                    $data['s_codes'] = unserialize("");
                    $condition['id'] = $val['id'];
                    $model->table($tableName)->where($condition)->save($data);#更新数据
                    if($number == 0){
                        break; #结束循环
                    }
                }else{
                    #MyLog::write("当前的购买数量小于当前该条记录的值");
                    #直接分配号码
                    $id = $val['id'];
                    $result2 = unserialize($val['s_codes']);
//                    ob_start();
//                    var_dump($result2);
//                    E(ob_get_contents(),403);
                    $code .= implode(',',array_splice($result2,0,$number));
                    #unset($condition);#消除$condition的影响
                    if($code){
                        $data['s_len'] = count($result2);
                        $data['s_codes'] = serialize($result2);
                        $condition['id'] = $id;
                        $result3 = $model->table($tableName)->where($condition)->save($data);#更新数据
                        if(!$result3){
                            return false;
                        }else{
                            break;#分配完成结束循环
                        }
                    }else{
                        return false;
                    }
                }
            }
            return $code;
        }else{
            #总数量小于用户购买数量
            return false;#直接返回false
        }
    }

    /**
     * @param $out_trade_no     交易订单号
     * @param $total_fee       交易金额
     * @param $transaction_id 交易单号
     */
    public function ping_notify($out_trade_no,$total_fee,$transaction_id){
        #获取账单是充值还是购物车付款
        $model  = new \Think\Model();
        $condition['code'] = $out_trade_no;
        $payType = $model->table('__MEMBER_ADDMONEY_RECORD__')->where($condition)->field('pay_type,status')->find();
        #MyLog::write('支付类型：'.$payType);
        #回调路由

        #判断订单的支付状态，如果是已支付，直接返回true，防止微信发送过多的信息
        if($payType['status'] == '已付款'){
            return true;
        }else{
            if($payType['pay_type'] == '在线支付'){
                #MyLog::write('进入在线支付');
                $result = $this->wxPayNotify($out_trade_no,$total_fee,$transaction_id);
            }elseif($payType['pay_type'] == '在线充值'){
                $result = $this->wxRechargeNotify($out_trade_no,$total_fee,$transaction_id);
            }else{
                return false;#否则不能回调
            }
        }

        return $result;
    }

    /**
     * 微信支付的回调
     */
    private function wxPayNotify($out_trade_no,$total_fee,$transaction_id){
        $model = new \Think\Model();
        #MyLog::write('进入pingNotify');
        #判断订单号是否存在
        $condition['code'] = $out_trade_no;
        $result = $model->table("__MEMBER_ADDMONEY_RECORD__")->field('uid,scookies,money')->where($condition)->find();

        #判断订单是否正确
        if($result){
            #MyLog::write('订单存在');
            #判断金额是否和数据库中的金额匹配
            if($result['money']*100 == $total_fee){
                 #MyLog::write('金额匹配');
                #获取用户表中的用户数据
                $userCondition['uid'] = $result['uid'];
                $userResult = $model->table("__MEMBER__")->field('uid,username,img,money')->where($userCondition)->find();
                #解析存储的订单数据
                #MyLog::write("用户信息".$userResult['username']);
                $orderData = unserialize($result['scookies']);
                #MyLog::write('orderdata'.ob_get_contents());
                #循环插入
                $status = "已付款,未发货,未完成";
                $type = "在线支付";
                $ip = $_SERVER['REMOTE_ADDR'];

                #开启事务
                $model->startTrans();
                #MyLog::write($model->getDbError());
                try{
                    #MyLog::write('进入try');
                    $time = time().".".rand(100,999);
                    foreach($orderData as $item){

                        #MyLog::write('进入循环');
                        #根据商品的id获取商品信息
                        $goodsCondition['id'] = $item['id'];
                        $goodsResult = $model->table("__SHOPLIST__")->field('title,qishu,shenyurenshu')->where($goodsCondition)->find();
                        #判断商品的剩余人数是否大于用户购买人数
                        if($goodsResult['shenyurenshu'] < $item['number']){
                            E('商品剩余数量小于购买数量',500);
                        }
                        #MyLog::write("商品信息：".$goodsResult['title'].':'.$goodsResult['qishu']);
                        #获取云购码 ,返回值是一个云购码串
                        $code = $this->getCode($item['id'],$goodsCondition['qishu'],$item['number']);
                        #MyLog::write("分配号码".$code);
                        #修改商品的数量
                        $updateResult = $model->execute("update __PREFIX__shoplist set `canyurenshu` = `canyurenshu` + ".$item['number'].",`shenyurenshu` = `shenyurenshu` -".$item['number']." where id=".$item['id']);
                        if(!$updateResult){
                            E('修改商品数量失败',500);
                        }

                        if($code){
                            #第二个number表示金额
                            $recordData[] = '("'.productionOrder('A').'","'. $userResult['username'] . '", "'. $userResult['img'] . '","'. $goodsResult['title'] .'","'. $goodsResult['qishu'] .'","'.$userResult['uid'].'","'.$item['id'].'","'.$item['number'].'","'.$time.'","'.$ip.'","'.$type.'","'.$item['number'].'","'.$code.'","'.$status.'")';
                        }else{
                            E('购买码分配失败',500);
                        }
                    }

                    $q1 =$model->execute("INSERT INTO __PREFIX__member_go_record (`code`,`username`,`uphoto`,`shopname`,`shopqishu`,`uid`,`shopid`,`gonumber`,`time`,`ip`,`pay_type`,`moneycount`,`goucode`,`status`) VALUES ".implode(',',$recordData));

                    $q2 = $model->execute("update __PREFIX__member_addmoney_record set `status` ='已付款',`transaction_id`='$transaction_id'  WHERE `code` ='$out_trade_no'");

                    $overgoods = array();
                    foreach($orderData as $item){
                        $goodsCondition['id'] = $item['id'];
                        $goodsResult = $model->table("__SHOPLIST__")->field('shenyurenshu,id')->where($goodsCondition)->find();
                        if($goodsResult['shenyurenshu'] == 0){
                            $q4 = $this->productLucklyNumber($goodsResult['id'],$time);
                            $this->autoNextPhase($goodsResult['id']);
                            $overgoods[] = $goodsResult['id'];
                        }else{
                            $q4 = true;
                        }
                    }

                    if($q1 && $q2&& $q4){
                        #MyLog::write('commit');
                        $model->commit();
                        if(!empty($overgoods)){
                            $this->sendUserWinMsg($overgoods);
                        }

                        return true;
                    }else{
                        #MyLog::write('微信支付修改记录失败');
                        E('发生了一个错误，修改支付记录失败',500);
                    }
                }catch (\Exception $e){
                    $model->rollback();
                    MyLog::write($model->getDbError());
                    #将用户的微信支付金额转到用户余额上
                    $ret = $this->gotoBalance($out_trade_no,$transaction_id);
                    if($ret){
                        return true;
                    }else {
                        return false;
                    }
                }
            }else{
                return false;
            }
        }else{
            return false;
        }

    }

    /**
     * 将用户的微信充值金额转到用户余额上
     */
    private function gotoBalance($out_trade_no,$transaction_id){
        $model = new \Think\Model();

        $model->startTrans();#开启事务

        $condition['code'] = $out_trade_no;
        $record = $model->table("__MEMBER_ADDMONEY_RECORD__")->field('uid,money')->find();
        $exe1 = $model->execute('update  __PREFIX__member set `money` = `money` +'.$record['money'].'where `uid` ='.$record['uid']);
        $exe2 = $model->execute("update __PREFIX__member_addmoney_record set `status` ='已付款',`transaction_id`=".$transaction_id."  WHERE code='$out_trade_no'");

        if($exe1 && $exe2){
            $model->commit();
            return true;
        }else{
            $model->rollback();
            return false;
        }
    }

    /**
     * 微信充值回调
     */
    private function wxRechargeNotify($out_trade_no,$total_fee,$transaction_id){
        $model = new \Think\Model();
        #MyLog::write('进入wxRechargeNotify');
        #判断订单号是否存在
        $condition['code'] = $out_trade_no;
        $result = $model->table("__MEMBER_ADDMONEY_RECORD__")->field('uid,money')->where($condition)->find();

        $where['uid'] = $result['uid'];
        $userMoney = $model->table('__MEMBER__')->where($where)->getField('money');
        $money = $userMoney + $result['money'];
        #判断订单是否正确
        if($result){
            #MyLog::write('订单存在');
            #判断金额是否和数据库中的金额匹配
            #MyLog::write($total_fee);
            if($result['money']*100 == $total_fee){
                # MyLog::write('金额匹配');
                $status = "已付款";
                $model->startTrans();
                #$result1 = $model->execute("update __PREFIX__member set money = ".$money." where uid = ".$result['uid']);
                #$result2 = $model->execute('update __PREFIX__member_addmoney_record set status='.$status.',transaction_id ='.$transaction_id." where code =".$out_trade_no);
                $data1['money'] = $money;
                $where1['uid'] = $result['uid'];
                $result1 = $model->table('__MEMBER__')->where($where1)->save($data1);

                $data2['status'] = $status;
                $data2['transaction_id'] = $transaction_id;
                $where2['code'] = $out_trade_no;
                $result2= $model->table('__MEMBER_ADDMONEY_RECORD__')->where($where2)->save($data2);

                if($result1 && $result2){
                    #MyLog::write('commit');
                    $model->commit();
                    return true;
                }else{
                    $model->rollback();
                    MyLog::write($model->getDbError());
                    return false;
                }
            }

        }
    }


    /**
     * 产生幸运号码和产生中奖的人
     */
    private function productLucklyNumber($gid,$endtime){
        $model = new \Think\Model();
        #获取商品的总需人数
        $record = $model->query("select __PREFIX__member_go_record.time from __PREFIX__member_go_record WHERE __PREFIX__member_go_record.time <".$endtime ." ORDER BY __PREFIX__member_go_record.time DESC limit 50");
        $total_human = $model ->query('select __PREFIX__shoplist.zongrenshu from __PREFIX__shoplist WHERE id = '.$gid);

//        ob_start();
//        var_dump($time);
//        MyLog::write("time:".ob_get_contents());
        #MyLog::write("endtime:".$endtime);
        $time_sum = 0;
        foreach($record as $item){
            $tmp = date("His",$item['time']);
            $rand_number = explode('.',$item['time']);
            $time_sum += intval($tmp.$rand_number[1]);#拼接字符串获取全站开奖前的前50条记录
            #MyLog::write($tmp.$rand_number[1]);
        }
        #MyLog::write("total_human:".$total_human[0]['zongrenshu']);
        #MyLog::write("time_sum:".$time_sum);
        #计算中奖号码
        $luckly_number =fmod($time_sum , $total_human[0]['zongrenshu'])+10000001;
        #MyLog::write("luckly_number:".$luckly_number);
        #member_go_record中查找中奖人信息
        $luckly_human = $model ->query("select id,uid,username,goucode from __PREFIX__member_go_record WHERE goucode LIKE '%$luckly_number%' and shopid = $gid");


        #$ret['luckly_human'] = $luckly_human;
        #$ret['luckly_number'] = $luckly_number;
        #修改数据库的中奖记录
        #修改shoplist的记录
        $result1 = $model->execute("update __PREFIX__shoplist set q_uid =".$luckly_human[0]['uid'].",q_user_code=".$luckly_number.",q_end_time=".$endtime." where id=$gid");
        #修改member_go_record记录
        $result2 = $model->execute("update __PREFIX__member_go_record set huode = $luckly_number WHERE id = ".$luckly_human[0]['id'] );
        if($result1 && $result2){
            return true;
        }else{
            MyLog::write("ERROR:".__FILE__."--function--productLucklyNumber sql:".$model->getLastSql() ." SQL-ERR:".$model->getDbError());
            return false;
        }
    }

    /**
     * 商品揭晓后自动进入下一期
     * 参数已购买完成的上一起的商品id
     */
    public function autoNextPhase($gid){
        #获取已结束的商品的信息
        $model = new \Think\Model();
        $lastGoods = $model -> query("select * from __PREFIX__shoplist WHERE id = $gid");
        #获取配置中中奖号的表后缀
        $condition['key'] = 'shopcodes_table';
        $shopcodes_table_Suffix = $model->table("__CACHES__")->where($condition)->getField('value');

        #添加数据到shoplist，主要数据包含替换数据参与人次，剩余人次，期数，时间，获奖id，获奖者号码，结束时间
        $data = array();#当前商品下一期商品的数组
        foreach($lastGoods as $val){
            $data['sid'] = $val['sid'];
            $data['cateid'] = $val['cateid'];
            $data['brandid']= $val['brandid'];
            $data['title'] = $val['title'];
            $data['title_style'] = $val['title_style'];
            $data['title2'] = $val['title2'];
            $data['keywords'] = $val['keywords'];
            $data['description'] = $val['description'];
            $data['money'] = $val['money'];
            $data['yunjiage'] = $val['yunjiage'];
            $data['zongrenshu'] = $val['zongrenshu'];
            $data['canyurenshu'] = 0;
            $data['shenyurenshu'] = $val['zongrenshu'];
            $data['def_renshu'] = $val['def_renshu'];
            $data['qishu'] = $val['qishu'] + 1;#期数加一
            $data['maxqishu'] = $val['max_qishu'];
            $data['thumb'] = $val['thumb'];
            $data['picarr'] = $val['picarr'];
            $data['content'] = $val['content'];
            #$data['codes_table'] = $val['codes_table'];#找到代码存放表名
            $data['codes_table'] = "shopcodes_table_".$shopcodes_table_Suffix;
            $data['xsjx_time'] = $val['xsjx_time'];
            $data['pos'] = $val['pos'];
            $data['renqi'] = $val['renqi'];
            $data['time'] = time();#时间获取当前更新的时间
            $data['order'] = $val['order'];
            $data['q_uid'] = null;
            $data['q_user'] = null;
            $data['q_user_code'] = null;
            $data['q_content'] = $val['q_content'];
            $data['q_counttime'] = $val['q_counttime'];
            $data['q_end_time'] = null;
            $data['q_showtime'] = $val['q_showtime'];
            $data['renqipos'] = $val['renqipos'];
            $data['newpos'] = $val['newpos'];
            $data['bannershop'] = $val['bannershop'];
            $data['posthumb'] = $val['posthumb'];
            $data['quyu'] = $val['quyu'];
        }

        $addResult = $model ->table("__SHOPLIST__")->add($data);
        #更具价格自动生成号码,并打乱数据的排序


        if($addResult){
            $code = array();
            #unserialize()的反序列大于3000的时候返回值为false的问题
            $total  = $data['zongrenshu'];
            $num = 3000;
            #如果商品的总需人数小于等于3000，直接插入一条记录
            if($total <= $num){
                for($i = 1;$i <= $data['zongrenshu'];$i++){
                    $code[$i] = 10000000 + $i;
                }
//                $code = range(10000001,10000000+$data['zongrenshu']);
                #打乱数组
                shuffle($code);
                #序列化数据
                $code = serialize($code);
                #在代码表中插入序列化后的
                $data2['s_id'] = $addResult;
                $data2['s_cid'] = 1;
                $data2['s_len'] =  $data['zongrenshu'];
                $data2['s_codes'] = $code;
                $data2['s_codes_tmp'] = $code;
                $result2 = $model->table("__SHOPCODES_".$shopcodes_table_Suffix."__")->add($data2);
                if($result2){
                    return true;
                }else{
                    E("插入序列化的数据失败",500);
                    return false;
                }
            }else{
                #循环插入多条记录
                $ceil =ceil($total/$num);
                #先插入商次
                for($k=1;$k<$ceil;$k++){
                    #序列化3000个数字
                    for($i = 1;$i < 3000;$i++){
                        $code[$i] = 10000000 + $total;
                        $total--;
                    }
                    #打乱数据
                    shuffle($code);
                    #序列化
                    $code=serialize($code);
                    $data3['s_id'] = $addResult;
                    $data3['s_cid'] = $k;
                    $data3['s_len'] =  3000;
                    $data3['s_codes'] = $code;
                    $data3['s_codes_tmp'] = $code;
                    $query_1 = $model->table("__SHOPCODES_".$shopcodes_table_Suffix."__")->add($data3);
                    unset($code);
                }
                $surplus =  $data['zongrenshu'] - ($ceil - 1)*3000;#剩余改分配的数据
                if($total== 0 && $query_1){
                    return true;
                }else{
                    #分配剩余的号码
                    $code=array();
                    for($i=1;$i<=$surplus;$i++){
                        $code[$i]=10000000+$total;
                        $total--;
                    }
                    shuffle($code);
                    $code=serialize($code);
                    $data4['s_id'] = $addResult;
                    $data4['s_cid'] = $ceil;
                    $data4['s_len'] =  $surplus;
                    $data4['s_codes'] = $code;
                    $data4['s_codes_tmp'] = $code;
                    $query_2 = $model->table("__SHOPCODES_".$shopcodes_table_Suffix."__")->add($data4);
                    unset($code);
                }

                return $query_1 && $query_2;
            }
        }else{
            #MyLog::write("自动添加下一期的商品失败,ERROR:".$model->getLastSql());
            return false;
        }

    }

    /**
     * 发送中奖信息接口
     */
    private function sendUserWinMsg($goods_arr){
        $model = new \Think\Model();
        foreach($goods_arr as $item){
            $mfg = $model->query("select __PREFIX__user.openid,__PREFIX__shoplist.qishu,__PREFIX__shoplist.title from __PREFIX__member INNER JOIN __PREFIX__shoplist ON __PREFIX__shoplist.q_uid = __PREFIX__member.uid INNER JOIN __PREFIX__user ON __PREFIX__member.weixin_id = __PREFIX__user.id WHERE __PREFIX__shoplist.id = ".$item);
            $weixinapi =new WeixinApi();
            $weixinapi->sendText($mfg[0]['openid'],"恭喜您获得了\n商品名:".$mfg[0]['title']."\n商品期数:第".$mfg[0]['qishu']."期\n请您在个人中心的中奖记录中查看并确认收货地址，我们会尽快为您发货,如果您获得的是虚拟产品，请联系客服".C('Customer_service')."。感谢您的支持!");
            #MyLog::write($model->getLastSql());
        }
    }

    /* end of pay model */
}